

// json 深拷贝，第一种
export function deepCopy(oldData){
    if (typeof oldData==='object' && oldData !==null){
        let res = Array.isArray(oldData)?[]:{};
        for (let k in oldData){
            if (oldData.hasOwnProperty(k)){
                res[k] = deepCopy(oldData[k]);
            }
        }
        return res
    } else {
        return oldData
    }
}



/**
 * 首次调用时，weakMap为空，不会走上面那个if(hash.has())语句，
 * 如果待拷贝对象中有属性也为对象时，则将该待拷贝对象存入weakMap中，此时的健值和健名都是对该待拷贝对象的引用
 * 然后递归调用该函数
 * 再次进入该函数，传入了上一个待拷贝对象的对象属性的引用和存储了上一个待拷贝对象引用的weakMap，
 * 因为如果是循环引用产生的闭环，那么这两个引用是指向相同的对象的，因此会进入if(hash.has())语句内，然后return，退出函数，所以不会一直递归进栈，以此防止栈溢出。
* **/
// json 深拷贝，第二种
export function deepCopy2(data, hash = new WeakMap()) {
    if(typeof data !== 'object' || data === null){
        throw new TypeError('传入参数不是对象')
    }
    // 判断传入的待拷贝对象的引用是否存在于hash中
    if(hash.has(data)) {
        return hash.get(data)
    }
    let newData = {};
    const dataKeys = Object.keys(data);
    dataKeys.forEach(value => {
        const currentDataValue = data[value];
        // 基本数据类型的值和函数直接赋值拷贝
        if (typeof currentDataValue !== "object" || currentDataValue === null) {
            newData[value] = currentDataValue;
        } else if (Array.isArray(currentDataValue)) {
            // 实现数组的深拷贝
            newData[value] = [...currentDataValue];
        } else if (currentDataValue instanceof Set) {
            // 实现set数据的深拷贝
            newData[value] = new Set([...currentDataValue]);
        } else if (currentDataValue instanceof Map) {
            // 实现map数据的深拷贝
            newData[value] = new Map([...currentDataValue]);
        } else {
            // 将这个待拷贝对象的引用存于hash中
            hash.set(data,data)
            // 普通对象则递归赋值
            newData[value] = deepCopy(currentDataValue, hash);
        }
    });
    return newData;
}



